工作開發一陣子才發現有些習以為常的功能對別人來說很...陌生,像是網頁常常遇到的 Dialog / Modal (對話視窗),大部分都可以透過點擊「外面」來關掉(也就是Dialog之外的區域),但有遇到使用者問我:「怎麼關?」,我:「ㄜ...點外面...?」
UX 好難 OAO?
前幾篇也有使用到 Dialog 來當作範例,Dialog 通常做為「進一步的動作」,由於對使用者操作上的干擾度很高,因此像執行比較危險的動作時 (例如刪除),都會再一次提醒使用者;一方面也可以作為資訊的延伸或是表單的填寫。 (有興趣的朋友可以閱讀這篇 - 5 Essential UX Rules for Dialog Design)
好,回到前端正題,大部分的 Dialog 以及一些選單類型 (Menu / Drawer / Popover),都會渲染在 document.body
的最後一個子元素,可以確保 stacking context 使整個元素渲染在「最上面」,有些也使用 position + zIndex 組合技來確保元素呈現在最上面。
於是自己先來 survey 一圈:
<Modal />
來看,就是透過 ReactDOM.createPortal 的方式將其渲染「最上面」。並設置 1400 的 zIndex。關掉的方式除了從裡面,外面就是透過點擊 overlay 來觸發關閉。<AutoComplete/>
來看,有提供 disablePortal 的 prop,選單則會渲染在原本節點一旁,有仍然透過 zIndex 來讓整個元素呈現在最上面。關閉的方式除了從內部點擊選項之外,由於本身也有用 input 組合,foucs時開始選單,點擊外圍會觸發 blur,再進一步關閉元件。node.contains(element)
//轉換成人話就是: Dialog 有沒有包含 剛剛點擊的元素(event.target)
類似的作法可以在這些components or hooks:
做完一輪 survey 之後,我們確切要做什麼呢?
撇開彈出式的內容是不是本意要阻擋使用者,我們都希望能夠透過點擊外側來快速離開,或是在互動性較高的網站上也能自由運用,因此要來製作一個點「外面」的Hook,方向則是使用上述的第三點來實作,實作過程就留到下一篇吧!